package Day10_Ex3_queues1;

/**
 * TicketCounter demonstrates the use of a queue for simulating a waiting line.
 *
 * @author Dr. Lewis
 * @author Dr. Chase
 * @version 1.0, 08/12/08
 */
public class TicketCounter
{

    final static int PROCESS = 120;
    final static int MAX_CASHIERS = 10;
    final static int NUM_CUSTOMERS = 100;
    final static int CUSTOMER_ARRIVAL_INTERVAL = 15;

    public static void main(String[] args)
    {
        Customer customer;

        //Either an array based or linked list data structure can be used.
        QueueADT<Customer> customerQueue = new CircularArrayQueue<Customer>();
        //QueueADT<Customer> customerQueue = new LinkedQueue<Customer>();

        int[] cashierTime = new int[MAX_CASHIERS];
        int totalTime, averageTime, departs;

        /** process the simulation for various number of cashiers */
        for (int cashiers = 0; cashiers < MAX_CASHIERS; cashiers++)
        {
            /** set each cashiers time to zero initially*/
            for (int count = 0; count < cashiers; count++)
            {
                cashierTime[count] = 0;
            }

            /** load customer queue */
            for (int count = 1; count <= NUM_CUSTOMERS; count++)
            {
                customerQueue.enqueue(new Customer(count * CUSTOMER_ARRIVAL_INTERVAL));

                //Print out the predicted arrival times for all customers
                if (cashiers == 0)
                {
                    System.out.println("Customer[" + count + "] arrives: " + count * CUSTOMER_ARRIVAL_INTERVAL + " ==> " + new Time(count * CUSTOMER_ARRIVAL_INTERVAL).toString());
                }
            }
            totalTime = 0;

            /** process all customers in the queue */
            while (!(customerQueue.isEmpty()))
            {
                for (int count = 0; count <= cashiers; count++)
                {
                    if (!(customerQueue.isEmpty()))
                    {
                        customer = customerQueue.dequeue();

                        //Print out the arrival time and current time of each cust and cashier.
                        System.out.println("\nCashier[" + count + "] running time : " + cashierTime[count]);
                        System.out.println("Customer arrival time: " + customer.getArrivalTime());



                        if (customer.getArrivalTime() > cashierTime[count])
                        {
                            System.out.println("Customer does not have to wait");
                            departs = customer.getArrivalTime() + PROCESS;
                        } else
                        {
                            departs = cashierTime[count] + PROCESS;
                            System.out.println("Customer had to wait " + (cashierTime[count] - customer.getArrivalTime()) + "secs");

                        }

                        System.out.println("Customer departs @ " + departs);

                        customer.setDepartureTime(departs);
                        cashierTime[count] = departs;
                        totalTime += customer.totalTime();
                    }
                }
            }

            /** output results for this simulation */
            averageTime = totalTime / NUM_CUSTOMERS;
            System.out.println("\n\t\tNumber of cashiers: " + (cashiers + 1));
            System.out.println("\t\tAverage time: " + averageTime + " ==> " + new Time(averageTime).toString() + "\n");
        }
    }
}
